﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
using System.Windows.Input;

namespace Pavilion.DesignerTool.ViewTools
{
    public delegate void ConnectionCompleteHandler(ListBoxItem startItem, ListBoxItem endItem);
    public static class ConnectionManager
    {
        #region IsConnectableProperty

        public static readonly DependencyProperty IsConnectableProperty = DependencyProperty.RegisterAttached("IsConnectable", typeof(Boolean), typeof(ConnectionManager),
            new FrameworkPropertyMetadata());

        public static void SetIsConnectable(DependencyObject element, bool value)
        {
            element.SetValue(IsConnectableProperty, value);
        }

        public static Boolean GetIsConnectable(DependencyObject element)
        {
            return (bool)element.GetValue(IsConnectableProperty);
        }
                
        #endregion

        #region AnchorGridStyleProperty

        public static readonly DependencyProperty AnchorGridStyleProperty = DependencyProperty.RegisterAttached("AnchorGridStyle", typeof(Style),
            typeof(ConnectionManager), new PropertyMetadata(null));

        public static void SetAnchorGridStyleProperty(DependencyObject element, Style value)
        {
            element.SetValue(AnchorGridStyleProperty, value);
        }

        public static Style GetAnchorGridStyleProperty(DependencyObject element)
        {
            return (Style)element.GetValue(AnchorGridStyleProperty);
        }
        
        #endregion

        private static ListBoxItem startingListBox;
        private static ConnectionCompleteHandler connectionCompleteHandler;

        public static void BeginConnection(ListBoxItem startingListBox, ConnectionCompleteHandler connectionCompleteHandler)
        {
            ConnectionManager.startingListBox = startingListBox;
            ConnectionManager.connectionCompleteHandler = connectionCompleteHandler;
            var itemsPanel = PavilionVisualTreeHelper.GetAncestor<Canvas>(startingListBox);

            Point lineAdornerStart = DragAwareListBoxItem.GetPointOnCenter(startingListBox);
            LineAdorner lineAdorner = new LineAdorner(itemsPanel, lineAdornerStart);
            AdornerLayer.GetAdornerLayer(itemsPanel).Add(lineAdorner);

            lineAdorner.MouseLeftButtonDown += new MouseButtonEventHandler(LineAdorner_MouseLeftButtonDown);
        }

        private static void LineAdorner_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            var lineAdorner = sender as LineAdorner;
            ListBoxItem endItem = GetHitListBoxItem(lineAdorner, e);

            if (endItem != null && connectionCompleteHandler != null)
                connectionCompleteHandler.Invoke(startingListBox, endItem);

            FreeLineAdorner(lineAdorner);
        }

        private static void FreeLineAdorner(LineAdorner lineAdorner)
        {
            lineAdorner.ReleaseMouseCapture();
            lineAdorner.MouseLeftButtonDown -= new MouseButtonEventHandler(LineAdorner_MouseLeftButtonDown);
            AdornerLayer.GetAdornerLayer(lineAdorner.AdornedElement).Remove(lineAdorner);
        }
        
        private static ListBoxItem GetHitListBoxItem(LineAdorner lineAdorner, MouseButtonEventArgs e)
        {
            ListBoxItem hitItem = null;

            VisualTreeHelper.HitTest(lineAdorner.AdornedElement, null,
                hitTestParameters: new PointHitTestParameters(e.GetPosition(lineAdorner.AdornedElement)),
                resultCallback: (HitTestResult result) =>
                {
                    hitItem = PavilionVisualTreeHelper.GetAncestor<ListBoxItem>(result.VisualHit);
                    return HitTestResultBehavior.Stop;
                });

            return hitItem;
        }
    }
}
